import React, { Component } from 'react';
import { Button, Upload } from 'antd';
import * as api from '@/constants/api';
import { UploadOutlined } from '@ant-design/icons';
import { LOGIN_COOKIE_KEY } from '@/constants';
import {
  HttpRequestHeader,
  UploadFile,
  UploadChangeParam,
  RcFile,
} from 'antd/lib/upload/interface';
import Cookies from 'js-cookie';
import { toast } from '@/utils/utils';

interface IState {
  fileList: UploadFile<any>[];
  uploading: boolean;
}

interface IProps {
  uploadUrl?: string;
  uploadParams?: object; // saveDir, keepName
  extList?: string[];
  fileSize?: number;
  uploadText?: string;
  btnProps?: object;
  uploadSuc?: (fileUrl: string) => void;
  uploadErr?: () => void;
  showLoading?: boolean;
}

interface UploadBtn {
  headers: HttpRequestHeader;
}

class UploadBtn extends Component<IProps, IState> {
  static defaultProps = {
    uploadUrl: api.UPLOAD_OSS,
    extList: [],
    fileSize: 5,
    uploadText: '上传',
    btnProps: {},
    showLoading: false,
  };

  constructor(props: IProps) {
    super(props);

    this.state = {
      fileList: [],
      uploading: false,
    };

    const token = Cookies.get(LOGIN_COOKIE_KEY);
    this.headers = {
      accessKey: token || '',
    };
  }

  onChange = (params: UploadChangeParam) => {
    const { uploadSuc, uploadErr } = this.props;
    this.setState({
      fileList: [...params.fileList],
      uploading: params.file.status === 'uploading',
    });
    if (
      params.file.status === 'done' &&
      params.file.response &&
      params.file.response.code === 2000
    ) {
      const fileUrl = params.file.response.data;
      if (uploadSuc) {
        uploadSuc(fileUrl);
      }
    } else if (params.file.status === 'error') {
      if (uploadErr) {
        uploadErr();
      }
    }
  };

  beforeUpload = (file: RcFile) => {
    const { extList, fileSize } = this.props;
    if (Array.isArray(extList) && extList.length > 0) {
      const extValid = extList.some(ext => file.name.endsWith(ext));
      if (!extValid) {
        toast(`格式不对，只允许上传以下格式：${extList.join(' ')}`, 'error');
        return false;
      }
    }

    if (fileSize) {
      if (file.size / 1024 / 1024 > fileSize) {
        toast(`文件过大，不能大于${fileSize}M`, 'error');
        return false;
      }
    }

    return true;
  };

  render() {
    const { uploadText, btnProps, showLoading, uploadUrl, uploadParams } = this.props;
    const { fileList, uploading } = this.state;

    return (
      <Upload
        action={uploadUrl}
        headers={this.headers}
        onChange={this.onChange}
        fileList={fileList}
        beforeUpload={this.beforeUpload}
        showUploadList={false}
        data={uploadParams}
      >
        <Button
          loading={showLoading && uploading}
          type="primary"
          icon={<UploadOutlined />}
          {...btnProps}
        >
          {uploadText}
        </Button>
      </Upload>
    );
  }
}

export default UploadBtn;
